#!/bin/env python
# coding:utf-8

import os
import os.path
import sys
import getopt
import time

''' 
pojo template
private Type var;
public Type getVar() {
	return this.var;
} 
public void setVar(Type var) {
	this.var = var;
}
'''

# TODO: modify it by yourself
typemap = {
	'char'	: 'String',
	'int'	: 'long',
	'date'	: 'Date',
	'varchar' : 'String',
	'decimal' : 'double'
}

windowslineend = '\r\n'
linuxlineend = '\n'

selectlineend = linuxlineend
middlefile = ''
user = ''
password = ''
database = ''
table = ''
host = ''
nowtime = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time()))

def getmaptype(dbtype):
	tmptype = dbtype.lower()
	if tmptype.startswith("char"):
		return typemap['char']
	elif tmptype.startswith("varchar"):
		return typemap['varchar']
	elif tmptype.startswith('int'):
		return typemap['int']
	elif tmptype.startswith('date'):
		return typemap['date']
	elif tmptype.startswith('decimal'):
		return typemap['decimal']
	else:
		return None

def getmiddlefile(user, password, database, table):
	if host == '':
		cmdline = 'echo "use ' + database + '; desc ' + table + ';"| mysql -u' + user + ' -p' + password + '>' + table + ".mpojo"
	else:
		cmdline = 'echo "use ' + database + '; desc ' + table + ';"| mysql -h' + host + ' -u' + user + ' -p' + password + '>' + table + ".mpojo"
		
	print cmdline
	if os.system(cmdline) != 0:
		return -1

class columninfo(object):
	# Field   Type    Null    Key     Default Extra --> only user Field and Type(elements[0] and elements[1])
	def __init__(self, linestr):
		self.linestr = linestr
		self.elements = []
		if linestr == None or linestr == '':
			return None
	def parseline(self):
		tmp_elements = self.linestr.split('\t')
		self.elements = tmp_elements
				
class genpojo(object):
	def __init__(self, pathfilename):
		self.pathfilename = pathfilename
		self.genfilebuffer = ''
		self.file = None
		self.columns = []
	
	def openfile(self):
		try:
			self.file = open(self.pathfilename, 'rb')
		except Exception as e:
			return -1

	def parsefile(self):
		linebuffer = ''
		isFirstLine = True
		while True:
			linebuffer = self.file.readline(1024)	
			if linebuffer == '':
				break
			if isFirstLine == True:
				isFirstLine = False
				continue

			column = columninfo(linebuffer)
			if column == None:
				return -1
			column.parseline()	#parse line
			self.columns.append(column)

	def genvars(self):
		for column in self.columns:
			javatype = getmaptype(column.elements[1])
			if javatype == None:
				print 'type convert error: ' + column.elements[1]
				return -1
			line = '\tprivate ' + javatype + ' ' +  column.elements[0] + ';\n'
			self.genfilebuffer += line

		self.genfilebuffer += '\n'

	def genfileheader(self):
		uppertable = table[0].upper() + table[1:]
		self.genfilebuffer += '/* <<< this file generated by "genpojo" --- ' + nowtime + ' >>> */\n\n'
		self.genfilebuffer += 'import javax.xml.bind.annotation.XmlRootElement;\nimport java.io.Serializable;\nimport java.sql.Date;\n\n@XmlRootElement\npublic class ' + uppertable + ' implements Serializable {\n\n'

	def genfileend(self):
		self.genfilebuffer += '}\n'

	def genmethod(self):
                for column in self.columns:
                        javatype = getmaptype(column.elements[1])
                        if javatype == None:
                                print 'type convert error: ' + column.elements[1]
                                return -1
			upperfiled = column.elements[0][0].upper() + column.elements[0][1:]
                        getline = '\tpublic ' + javatype + ' get' +  upperfiled + '() {\n\t\treturn self.' + column.elements[0] + ';\n\t}\n'
                        self.genfilebuffer += getline
			setline = '\tpublic void set' + upperfiled + '(' + javatype + ' ' + column.elements[0] + ') {\n\t\tself.' + column.elements[0] + ' = ' +  column.elements[0] + ' ;\n\t}\n'
			self.genfilebuffer += setline
			self.genfilebuffer += '\n'
	def writefile(self):
		genfile = None
		try:
			uppertable = table[0].upper() + table[1:]
                        genfile = open(uppertable+ '.pojo', 'w+')
                except Exception as e:
                        return -1

		genfile.write(self.genfilebuffer)
		genfile.close()
			 
	def genpojo(self):
		if self.openfile() == -1:
			print 'open ' + self.pathfilename + ' error'
			return -1
			
		if self.parsefile() == -1:
			print 'parse file error'
			return -1

		if self.genfileheader() == -1:
			print 'generate file header error'
			return -1

		if self.genvars() == -1:
			print 'generate var error'	
			return -1

		if self.genmethod() == -1:
			print 'generate method error'
			return -1

		if self.genfileend() == -1:
			print 'generate file footer error'
			return -1

		if self.writefile() == -1:
			print 'write generate file error'
			return -1
		
#short opt: 'hi:o:' h only an onoff type, but i and o can with arg
#long opt:["version", "file="] we can user --version, but if we want to with arg, we should user 'file='
#args:directly append characters with exe.py
if __name__ == '__main__':
	opts, args = getopt.getopt(sys.argv[1:], 'f:whd:t:u:p:i:')
	directfileflag = False
	desccmdflag = False

	for opt in opts:
		if  opt[0] == '-h':
			print '<<<<<<<HELP INFORMATION>>>>>>>\n-f: read mysql table descript(direct file)\n\
-w: generate pojo file used in windhows\n\
-h: show help\n\
-u: mysql user(middlefile)\n\
-p: mysql user\'s password(middlefile)\n\
-d: use which database(middle file)\n\
-t: use which table(both two)\n\
-i: mysql host name or ip address(middlefile)\n'
			exit(1)

		elif opt[0] == '-f':
			directfileflag = True	
			middlefile = opt[1]
			if middlefile == None or middlefile == '':
				print 'input middle file'
				exit(1)

		elif opt[0] == '-w':
			selectlineend = windowslineend

		elif opt[0] == '-u':
			desccmdflag = True
			user = opt[1]	
			if user == None or user == '':
				print 'input mysql database user'
				exit(1)

		elif opt[0] == '-p':
			desccmdflag = True
			password = opt[1]	
			if password == None or password == '':
				print 'input mysql database password'
				exit(1)
		elif opt[0] == '-d':
			desccmdflag = True
			database = opt[1]	
			if database == None or database == '':
				print 'input mysql database name'
				exit(1)
		elif opt[0] == '-t':
			desccmdflag = True
			table = opt[1]	
			if table == None or table == '':
				print 'input mysql table name'
				exit(1)
                elif opt[0] == '-i':
                        desccmdflag = True
                        host = opt[1]
                        if host == None or host == '':
                                print 'input mysql host name or ip address'
                                exit(1)

	if desccmdflag == True and directfileflag == True:
		print 'opts error conflict!'
		exit(1)

	if desccmdflag == True:
		if user == '' or password == '' or database == '' or table == '':
			print 'opts not enough!'
			exit(1)
		else:
			if getmiddlefile(user, password, database, table) == -1:
				print 'get middle file error'
				exit(1)
			else:
				middlefile = table + ".mpojo"
	elif directfileflag == True:
		if middlefile == '' or table == '':
			print 'opts not enough!'
			exit(1)

	if middlefile == None or middlefile == '':
		print 'internal error'
		exit(1)	
	print 'middle file:' + middlefile
	tool = genpojo(middlefile)
	if tool.genpojo() == -1:
		print 'generate failed!'
	else:
		uppertable = table[0].upper() + table[1:]
		print 'generate file ' + uppertable + '.pojo success'
	
	os.remove(middlefile)	